package com.yi.serviceprice.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yi.internalcommon.constant.CommonStatusEnum;
import com.yi.internalcommon.dto.PriceRule;
import com.yi.internalcommon.dto.ResponseResult;
import com.yi.internalcommon.request.ForecastPriceDTO;
import com.yi.internalcommon.responese.DirectionResponse;
import com.yi.internalcommon.responese.ForecastPriceResponse;
import com.yi.internalcommon.util.BigDecimalUtils;
import com.yi.serviceprice.mapper.PriceRuleMapper;
import com.yi.serviceprice.remote.ServiceMapClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

@Service
@Slf4j
public class ForecastPriceService {
    @Autowired
    private ServiceMapClient serviceMapClient;
    @Autowired
    private PriceRuleMapper priceRuleMapper;

    /**
     * 调用地图服务，查询距离和时长，计算预估价格
     *
     * @param depLongitude
     * @param depLatitude
     * @param destLongitude
     * @param destLatitude
     * @return
     */
    public ResponseResult forecastPrice(String depLongitude, String depLatitude, String destLongitude, String destLatitude
    ,String cityCode,String vehicleType) {
        log.info("调用地图服务，查询距离和时长");
        ForecastPriceDTO forecastPriceDTO = new ForecastPriceDTO();
        forecastPriceDTO.setDepLatitude(depLatitude);
        forecastPriceDTO.setDepLongitude(depLongitude);
        forecastPriceDTO.setDestLatitude(destLatitude);
        forecastPriceDTO.setDestLongitude(destLongitude);
        ResponseResult<DirectionResponse> direction = serviceMapClient.direction(forecastPriceDTO);
        DirectionResponse data = direction.getData();
        Integer distance = data.getDistance();
        Integer duration = data.getDuration();
        log.info("距离：" + distance + ";时间：" + duration);
        log.info("读取计价规则");
        LambdaQueryWrapper<PriceRule> lqw = new LambdaQueryWrapper<>();
        lqw.eq(PriceRule::getCityCode, cityCode);
        lqw.eq(PriceRule::getVehicleType, vehicleType);
        lqw.orderByDesc(PriceRule::getFareVersion);
        List<PriceRule> priceRules = priceRuleMapper.selectList(lqw);

        if (priceRules == null || priceRules.size()==0) {
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(), CommonStatusEnum.PRICE_RULE_EMPTY.getValue());
        }
        PriceRule priceRule = priceRules.get(0);
        log.info("计价规则：" + priceRules.get(0));
        log.info("根据距离和时长和计价规则，计算价格");

        double price = getPrice(priceRule, distance, duration);

        ForecastPriceResponse response = new ForecastPriceResponse();
        response.setPrice(price);
        response.setCityCode(cityCode);
        response.setVehicleType(vehicleType);
        response.setFareType(priceRule.getFareType());
        response.setFareVersion(priceRule.getFareVersion());
        return ResponseResult.success(response);
    }

    /**
     * 计算实际价格
     * @param distance
     * @param duration
     * @param cityCode
     * @param vehicleType
     * @return
     */
    public ResponseResult<Double> calculatePrice(Integer distance, Integer duration, String cityCode, String vehicleType) {
        //查询计价规则
        LambdaQueryWrapper<PriceRule> lqw = new LambdaQueryWrapper<>();
        lqw.eq(PriceRule::getCityCode, cityCode);
        lqw.eq(PriceRule::getVehicleType, vehicleType);
        lqw.orderByDesc(PriceRule::getFareVersion);
        List<PriceRule> priceRules = priceRuleMapper.selectList(lqw);

        if (priceRules == null || priceRules.size()==0) {
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(), CommonStatusEnum.PRICE_RULE_EMPTY.getValue());
        }
        PriceRule priceRule = priceRules.get(0);

        log.info("计价规则：" + priceRules.get(0));

        log.info("根据距离和时长和计价规则，计算价格");

        double price = getPrice(priceRule, distance, duration);
        return ResponseResult.success(price);
    }

        /**
         * 根据距离和时长计算价格
         *
         * @param priceRule 规则
         * @param distance  距离
         * @param duration  时长
         * @return
         */
    public static double getPrice(PriceRule priceRule, Integer distance, Integer duration) {
        double price = 0;
        //起步价
        double startFare = priceRule.getStartFare();
        price= BigDecimalUtils.add(price,startFare);
        //里程费
        //总里程 km
        double distanceMile = BigDecimalUtils.divide(distance,1000);
        //起步里程
        double startMile = priceRule.getStartMile();
        //最终收费里程 km
        double distancesubtract = BigDecimalUtils.substract(distanceMile,startMile);
        double mile = distancesubtract > 0 ? distancesubtract : 0;
        //计程单价 元/km
        double unitPricePerMile = priceRule.getUnitPricePerMile();
        //里程价格
        double mileFare = BigDecimalUtils.multiply(mile,unitPricePerMile);
        price= BigDecimalUtils.add(price,mileFare);
        //分钟时长
        double time = BigDecimalUtils.divide(duration,60);
        //计时单价
        double unitPricePerMinute = priceRule.getUnitPricePerMinute();
        //时长费用
        double timeFare =BigDecimalUtils.multiply(time,unitPricePerMinute);
        price= BigDecimalUtils.add(price,timeFare);

        BigDecimal priceBigDecimal = BigDecimal.valueOf(price);
        priceBigDecimal= priceBigDecimal.setScale(2, RoundingMode.HALF_UP);

        return priceBigDecimal.doubleValue();
    }

//    public static void main(String[] args) {
//        PriceRule priceRule = new PriceRule();
//        priceRule.setUnitPricePerMile(1.8);
//        priceRule.setUnitPricePerMinute(0.5);
//        priceRule.setStartFare(10.0);
//        priceRule.setStartMile(3);
//        System.out.println(getPrice(priceRule,6500, 1800));
//    }
}
